package org.alvin.dispatchtcp.bean;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ipfilter.RuleBasedIpFilter;
import io.netty.handler.timeout.IdleStateHandler;
import org.alvin.dispatchtcp.handler.DispatchClientHandler;
import org.alvin.dispatchtcp.handler.DispatchServerHandler;

import java.beans.PropertyChangeSupport;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

public class DispatchServer extends PropertyChangeSupport {

    private Vector<ServerNode> proxyServerList = new Vector<>();

    public DispatchServer( ) {
        super("");
    }


    public void addServer(ServerNode serverNode){
        proxyServerList.add(serverNode);
        firePropertyChange("addServerNode",false,serverNode);
    }

    public void start(){
        new Thread(() -> {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup(20);

            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel socketChannel) throws Exception {
                                socketChannel.pipeline()
                                        .addLast(new DispatchServerHandler(DispatchServer.this));
                            }
                        })
                        .option(ChannelOption.SO_BACKLOG, 128)
                        .childOption(ChannelOption.SO_KEEPALIVE, true);
                ChannelFuture f = b.bind(8087).sync();
                f.channel().closeFuture().sync();
            } catch (Exception t) {
                t.printStackTrace();
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        }).start();
    }

    public Vector<ServerNode> getServers() {
        return this.proxyServerList;
    }
}
